package de.fhwgt.quiz.loader;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import de.fhwgt.quiz.application.Catalog;
import de.fhwgt.quiz.application.Question;

public class FilesystemLoader implements CatalogLoader {


    private File[] catalogDir;
    private final Map<String, Catalog> catalogs =
        new HashMap<String, Catalog>();
    private final String location;

    public FilesystemLoader(String location) {
        this.location = location;
    }

    @Override
    public Map<String, Catalog> getCatalogs() throws LoaderException {

        if (!catalogs.isEmpty()) {
            return catalogs;
        }

        // Construct URL for package location
        URL url = this.getClass().getClassLoader().getResource(location);

        File dir;
        try {
            // Make sure the Java package exists
            if (url != null) {
                dir = new File(url.toURI());
            } else {
                dir = new File("/");
            }
        } catch (URISyntaxException e) {
            // Try to load from the root of the classpath
            dir = new File("/");
        }

        // Add catalog files
        if (dir.exists() && dir.isDirectory()) {
            this.catalogDir = dir.listFiles(new CatalogFilter());
            for (File f : catalogDir) {
                catalogs.put(f.getName(),
                    new Catalog(f.getName(), new QuestionFileLoader(f)));
            }
        }

        return catalogs;
    }

    @Override
    public Catalog getCatalogByName(String name) throws LoaderException {
        if (catalogs.isEmpty()) {
            getCatalogs();
        }

        return this.catalogs.get(name);
    }

    /**
     * Filter class for selecting only files with a .xml extension.
     *
     * @author Simon Westphahl
     *
     */
    private class CatalogFilter implements FileFilter 
    {

        /**
         * Accepts only files with a .xml extension.
         */
        @Override
        public boolean accept(File pathname) {
            if (pathname.isFile() && pathname.getName().endsWith(".xml"))
                return true;
            else
                return false;
        }

    }

    private class QuestionFileLoader implements QuestionLoader
    {

        private final File catalogFile;
        private final List <Question> questions = new ArrayList<Question>();

        public QuestionFileLoader(File file) {
            catalogFile = file;
        }
        @Override
        public List<Question> getQuestions(Catalog catalog) throws LoaderException 
        {
            if (!questions.isEmpty()) 
            {
                return questions;
            }

            SAXBuilder builder;
            builder = new SAXBuilder();
            Document document;
			try {
				document = (Document) builder.build(catalogFile);
			} catch (JDOMException | IOException e) {
				e.printStackTrace();
				throw new LoaderException();
			}
            Element rootNode = document.getRootElement();
			List<Element> questionElements = rootNode.getChildren("frage");

            // Search the whole file for questions
			for(int i = 0; i < questionElements.size(); i++)
			{
				//Das aktuelle Element des Schleifendurchlaufs
				Element elementQuestion = questionElements.get(i);
				//Erzeugt ein neues Fragenobjekt mit dem Text des Elements als Fragentext
                Question question = new Question(elementQuestion.getChildText("text"));

                
                //Setzen des Timeouts (falls vorhanden)
                if (elementQuestion.getChild("timeout") != null) 
                {
                    question.setTimeout(Long.parseLong(elementQuestion.getChild("timeout").getAttributeValue("time")));
                }

                //Setzen der Antwortmoeglichkeiten
                List<Element> answerElements = elementQuestion.getChildren("antwort");
                for(int j = 0; j < answerElements.size(); j++)
                {
                	//Das aktuelle Element des Schleifendurchlaufs
    				Element elementAnswer = answerElements.get(j);
    				
	                if(Boolean.parseBoolean(elementAnswer.getAttributeValue("richtig")))
	                {
	                    question.addAnswer(elementAnswer.getText());
	                }else{
	                    question.addBogusAnswer(elementAnswer.getText());
	                }
                }

                // Make sure the question is complete
                if (question.isComplete())
                    // Add some randomization
                    question.shuffleAnswers();
                    questions.add(question);
            }
            return questions;
        }

    }
}
